package entity;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import javax.persistence.*;
import utils.OrderSubmitException;
import utils.ProductQuantityException;

@Entity
@Table(name="ORDER_TABLE")
@NamedQueries({
    @NamedQuery(name = "allUserOrders",
    query = "SELECT o FROM Order o WHERE o.user.id = :userId ORDER BY o.date DESC")
})
public class Order implements Serializable {

    private static final long serialVersionUID = 1L;
    private Long id;
    private Date date;
    private List<OrderItem> orderItems = new ArrayList<OrderItem>();
    private OrderStatus orderStatus = OrderStatus.UNPLACED;
    private User user;
    
    public void removeProduct(Product product){
        
        if (product != null) {
            
            Iterator<OrderItem> itr = orderItems.iterator();
            while (itr.hasNext()) {
                
                OrderItem orderItem = itr.next();
                if (orderItem.getProduct().equals(product)) {
                    itr.remove();
                    break;
                }
            }
        }
    }
     /**
     * Stelt de quantity van een product in.
     * Geef een quantity mee die kleiner is dan 0
     * en het product wordt uit de cart verwijderd.
     * 
     * @param product
     * @param quantity 
     */
    public void setProductQuantity(Product product, int quantity) throws ProductQuantityException{
        
       if(product != null){ 
            if (quantity > 0) {

                boolean found = false;
                for (OrderItem orderItem : orderItems) {
                    if (orderItem.getProduct().equals(product)) {
                        orderItem.setQuantity(quantity);
                        found = true;
                        break;
                    }
                }

                if (!found) {
                    OrderItem newOrderItem = new OrderItem();
                    newOrderItem.setOrder(this);
                    newOrderItem.setProduct(product);
                    newOrderItem.setQuantity(quantity);
                    orderItems.add(newOrderItem);
                }
            } else {
                throw new ProductQuantityException("Quantity is 0");
            }
       } else {
            throw new ProductQuantityException("Product is null");       
       }
    }
    
    public void clear(){
        if (orderStatus.equals(OrderStatus.UNPLACED)) {
            orderItems.clear();
        }
    }
    
    public void submit() throws OrderSubmitException {
        if (orderStatus.equals(OrderStatus.UNPLACED)) {
            if (!orderItems.isEmpty()) {
                orderStatus = OrderStatus.PLACED;
                date = new Date();
            }
            else {
                throw new OrderSubmitException("Order mag niet leeg zijn");
            }
        }
        else {
            throw new OrderSubmitException("Kan order niet plaatsen");
        }
    }

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }
    
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name="ORDER_DATE")
    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }
    
    @OneToMany(mappedBy = "order", cascade = CascadeType.PERSIST)
    public List<OrderItem> getOrderItems() {
        return orderItems;
    }

    public void setOrderItems(List<OrderItem> orderItems) {
        this.orderItems = orderItems;
    }
    
    public OrderStatus getOrderStatus() {
        return orderStatus;
    }

    public void setOrderStatus(OrderStatus orderStatus) {
        this.orderStatus = orderStatus;
    }
    
    @ManyToOne
    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }
    
    @Override
    public int hashCode() {
        int hash = 0;
        hash += (id != null ? id.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof Order)) {
            return false;
        }
        Order other = (Order) object;
        if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "entity.Order[ id=" + id + " ]";
    }
}
